'use strict';
/**
 * This is another file from yeoman original generator-angular
 * but its been heavy modified
 * you basically util.inherits this with the Generator class.
 * BTW this is for use with the sub-generators
 */
 var fs = require('fs');
 var q = require('q');
 var util = require('util');
 var path = require('path');
 var yeoman = require('yeoman-generator');
 var glob = require('glob');
 var chalk = require('chalk');
 var _ = require('underscore');
 _.mixin(require('underscore.inflections'));

 var nbUtils = require('./nb-utils.js');
 var nbPreference = require('./nb-preference');

 /**
  * Constructor
  */
 var Generator = module.exports = function() {

     yeoman.generators.NamedBase.apply(this, arguments);

     var bowerJson = {};

     try {
         bowerJson = require(path.join(process.cwd(), 'bower.json'));
     } catch (e) {
         // nothing to do here
     }

     if (bowerJson.name) {
         this.appname = bowerJson.name;
     } else {
         this.appname = path.basename(process.cwd());
     }

     if (!this.env.options.appPath && bowerJson.appPath) {
         this.env.options.appPath = bowerJson.appPath;
     }

     this.appname = _.slugify(_.humanize(this.appname));
     this.scriptAppName = bowerJson.moduleName || _.camelize(this.appname) + nbUtils.appName(this);
     this.cameledName = _.camelize(this.name);
     this.classedName = _.classify(this.name);
     // get back the settings
     this.settings = this.getPanesConfig();

     this.option('en' , {
         type: String,
         desc: 'Change to English'
     });

     this.lang = (this.settings) ? this.settings.lang : (this.options.cn ? 'cn' : 'en');

     var interactive = {
         type: String,
         desc: (this.lang==='cn') ? '交互方式' : 'Interactive mode'
     };

     this.option('interactive' , interactive);
     this.option('ia' , interactive);
     this.interactive = this.options.interactive || this.options.ia;
     // just run this here and see if it works
     this.setScriptAndPath();
 };

 util.inherits(Generator, yeoman.generators.NamedBase);

/**
 * just replace that repetivie call
 */
Generator.prototype.setScriptAndPath = function()
{
    this.jsVer = this.getPanesConfig('jsVer');
    this.scriptSuffix = this.jsVer === 'ES6' ? '.jsx' : '.js';
    this.sourceRoot(path.join(__dirname, '..', 'generators' , 'templates' , 'base' , this.jsVer));
};

 /**
  * add a template file
  */
 Generator.prototype.appTemplate = function(src, dest , destScriptSuffic)
 {
     var endScriptSuffix = destScriptSuffic || this.scriptSuffix;
     yeoman.generators.Base.prototype.template.apply(this, [
         src + this.scriptSuffix,
         path.join(this.env.options.appPath, dest.toLowerCase()) + endScriptSuffix
     ]);
 };

 /**
  * test the template file
  */
 Generator.prototype.testTemplate = function(src, dest)
 {
     if (!this.env.options.testPath) {
         this.env.options.testPath = path.join(this.env.options.appPath , 'client' , 'web' , 'test');
     }
     // @TODO need to fix this later about the test path
     yeoman.generators.Base.prototype.template.apply(this, [
         src + this.scriptSuffix,
         path.join(this.env.options.testPath, dest.toLowerCase()) + this.scriptSuffix
     ]);
 };

 /**
  * generate html template
  */
 Generator.prototype.htmlTemplate = function(src, dest)
 {
     yeoman.generators.Base.prototype.template.apply(this, [
         src,
         path.join(this.env.options.appPath, dest.toLowerCase())
     ]);
 };

 /**
  * this is for the client side to get the source root directory
  */
 Generator.prototype.getClientSourceRoot = function()
 {
     var sourceRootBase = path.join(__dirname , '..' , 'generators' , 'templates' , 'common' , 'app' , 'client');
     var sourceRoot = path.join(sourceRootBase , 'javascript');
     this.scriptSuffix = '.js';

     if (this.settings) {
         if (this.settings.client['scriptingLang']) {
             this.env.options.coffee = (this.settings.client['scriptingLang']==='CS');
             this.env.options.typescript = (this.settings.client['scriptingLang']==='TS');
         }
     }

     if (this.env.options.coffee) {
         sourceRoot = path.join( sourceRootBase , 'coffeescript');
         this.scriptSuffix = '.coffee';
     }

     if (this.env.options.typescript) {
         sourceRoot = path.join(sourceRootBase , 'typescript');
         this.scriptSuffix = '.ts';
     }

     this.sourceRoot(sourceRoot);
 };

 /**
  * this is getting re-use everywhere
  * 22.09.2015 add appPath parameter for use with client side sub generator
  */
 Generator.prototype.generateSourceAndTest = function(appTemplate, testTemplate, targetDirectory , appPath)
 {
     appPath = appPath || 'server';
     this.appTemplate(appTemplate, path.join(appPath , targetDirectory, this.name));
     this.testTemplate(testTemplate, path.join(targetDirectory, this.name));
 };

 /**
  * insert a route into the route template
  */
 Generator.prototype.getRouteEntry = function(routes)
 {
     // we need to have this fix point. because the app path keep changing!
     // @TODO use preference to find out the exact app path?
     var _path = path.resolve(process.cwd() , 'app' , 'config' , 'routes.js');
     var routes = require(_path);
     return routes;
 };

 /**
  * recreate a new route file
  */
 Generator.prototype.generateNewRoute = function(newRoutes)
 {
     var _this = this;
     var routes = _this.getRouteEntry();
     var allRoutes = (routes && _.isObject(routes)) ?  _.extend(routes , newRoutes) : allRoutes;
     var fileName = 'routes.js';
     var dest = path.join(_this.env.options.appPath, 'config' , fileName);
     // setup source root
     _this.sourceRoot(path.join(__dirname, path.join( '..' , 'generators' , 'templates','common','app','config')));
     // need to remove the original file
     fs.unlink(dest , function() {
         // then replace it with a new generated route template
         _this.routesDefinition = JSON.stringify(allRoutes , null , 4);
         yeoman.generators.Base.prototype.template.apply(_this, [
             fileName,
             dest
         ]);
     });
 };
 /**
  * getting back the panesjs config file
  */
 Generator.prototype.getPanesConfig = function(key)
 {
     return nbPreference.getConfig(key);
 };


 /**
  * ask if they want to exit and write to file
  * this was original develop inside the model/ but this could be useful to all
  */
 Generator.prototype._askIfWantToExit = function(message)
 {
     message = message || {cn: chalk.yellow('完成?') , en: chalk.yellow('Finish?')};
     var _this = this;
     var cb = _this.async();
     var defer = q.defer();
     _this.prompt({
         type: 'confirm',
         name: 'exit',
         message: message[_this.lang],
         default: false
     } , function(props)
     {
         cb();
         defer.resolve(props.exit);
     }.bind(this));
     // need to return it
     return defer.promise;
 };
